package com.fenghongzhang.lib_dialog.view

import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin

/**
 * 自定义五角星进度条View
 * 功能：显示五角星进度，支持开始、暂停、继续等操作
 */

class StarProgressView @JvmOverloads constructor(
    context:Context,
    attrs:AttributeSet?=null,
    defStyleAttr:Int=0
):View(context,attrs,defStyleAttr){

    //画笔对象
    private val paint=Paint(Paint.ANTI_ALIAS_FLAG).apply {
        style=Paint.Style.STROKE            //描边模式
        strokeWidth=8f                      // 增加线条宽度，从1f改为8f
        strokeJoin =Paint.Join.ROUND        //线条连接处为圆角
        strokeCap=Paint.Cap.ROUND          //线条端点为圆角
        textAlign=Paint.Align.CENTER       //文本对齐方式
        textSize=30f
    }

    //存储五角星路径
    private val starPath=Path()

    //存储进度路径
    private val progressPath=Path()

    //路径测量器，用于截取路径
    private val pathMeasure= PathMeasure()

    // 定义一个变量来存储加载进度，初始值为0
    private var progress=0f

    // 定义一个布尔变量来表示加载是否完成，初始值为false
    private var isCompleted=false

    // 定义一个ValueAnimator类型的变量来处理加载动画，初始值为null
    private var animator: ValueAnimator?=null

    // 定义一个可被外部设置的回调函数，用于在加载完成时执行，初始值为null
    var onLoadingFinished:(()->Unit)?=null

    //五角星的半径
    private var starRadius=0f
    //五角星的中心点
    private var centerX=0f
    private var centerY=0f

    /**
     * 判断加载动画是否正在运行
     * @return 如果加载动画正在运行，则返回true；否则返回false
     */
    fun isLoading()=animator?.isRunning==true


    /**
     * 判断加载动画是否处于暂停状态
     * @return 如果加载动画处于暂停状态，则返回true；否则返回false
     */
    fun isPaused()=animator?.isPaused==true

    /**
     * 获取当前加载状态
     * @return 当前的加载状态，可以是PAUSED、LOADING或IDLE
     */

    fun getState():LoadingState=when{
        isPaused()->LoadingState.PAUSED
        isLoading()->LoadingState.LOADING
        else->LoadingState.IDLE
    }

    /**
     * 当View大小改变时，计算五角星的尺寸和位置
     */
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        centerX = w / 2f
        centerY = h / 2f
        starRadius = min(w, h) / 2f - paint.strokeWidth
        createStarPath()
    }

    /**
     * 创建一个五角星形状的路径
     * 该方法用于初始化一个五角星形状的Path对象，用于后续的绘制操作
     */
    private fun createStarPath() {
        // 重置路径，确保��径数据的准确性
        starPath.reset()

        // 增大五角星的半径，从0.8f改为1.6f
        val outerRadius = starRadius * 1f
        val innerRadius = outerRadius * 0.4f

        // 计算五角星的点
        for (i in 0..10) {
            // 计算当前点的角度位置
            val angle = Math.PI * i / 5 - Math.PI / 2
            // 根据点的位置交替选择外接圆或内接圆半径
            val radius = if (i % 2 == 0) outerRadius else innerRadius
            // 计算点的x坐标
            val x = centerX + (radius * cos(angle)).toFloat()
            // 计算点的y坐标
            val y = centerY + (radius * sin(angle)).toFloat()

            // 第一个点作为路径的起点，其他点作为线段的终点
            if (i == 0) starPath.moveTo(x, y) else starPath.lineTo(x, y)
        }
        // 封闭路径，完成五角星形状的构建
        starPath.close()
    }

    /**
     * 绘制view
     */
    override fun onDraw(canvas: Canvas) {
        // 绘制背景五角星
        paint.style = Paint.Style.STROKE
        paint.color = Color.LTGRAY
        canvas.drawPath(starPath, paint)

        // 根据任务完成状态设置画笔颜色，绿色表示完成，蓝色表示未完成
        paint.color = if (isCompleted) Color.GREEN else Color.BLUE

        // 重置进度路径，确保绘制的路径是新鲜的，避免之前的绘制状态影响当前绘制
        progressPath.reset()

        // 设置路径测量对象，使其跟随星星路径，并准备进行路径的测量与绘制
        pathMeasure.setPath(starPath, true)

        // 根据当前进度，获取星星路径的相应部分，并将其存储在进度路径中，以备绘制
        pathMeasure.getSegment(0f, pathMeasure.length * progress, progressPath, true)

        // 在画布上绘制进度路径，使用之前设置的画笔颜色，以反映当前任务的完成状态
        canvas.drawPath(progressPath, paint)

        // 绘制中心文字
        paint.style = Paint.Style.FILL
        paint.color = if (isCompleted) Color.GREEN else Color.BLACK
        canvas.drawText(
            if (isCompleted) "完成" else "${(progress * 100).toInt()}%",
            centerX,
            centerY + (paint.descent() - paint.ascent())/4,
            paint
        )
    }
    fun toggleLoading() {
        when (getState()) {
            LoadingState.LOADING -> pauseLoading()
            LoadingState.PAUSED -> resumeLoading()
            LoadingState.IDLE -> startLoading()
        }
    }
    private fun startLoading() {
        // 设置加载状态为未完成
        isCompleted = false
        // 重置加载进度为0
        progress = 0f
        // 取消当前动画，如果有的话
        animator?.cancel()

        // 创建并配置新的动画
        animator = ValueAnimator.ofFloat(0f, 1f).apply {
            // 设置动画持续时间为5秒
            duration = 5000
            // 使用线性插值器以恒定速度变化
            interpolator = LinearInterpolator()
            // 设置动画更新监听器以实时更新进度
            addUpdateListener {
                progress = it.animatedValue as Float
                invalidate()
            }

            //设置动画监听器以处理动画结束时的逻辑

            addListener(object : Animator.AnimatorListener {
                override fun onAnimationStart(animation: Animator) {}
                override fun onAnimationEnd(animation: Animator) {
                    // 当动画结束时，设置加载状态为完成，并触发加载完成的回调
                    isCompleted = true
                    invalidate()
                    onLoadingFinished?.invoke()
                }
                override fun onAnimationCancel(animation: Animator) {}
                override fun onAnimationRepeat(animation: Animator) {}
            })
            start()
        }
    }




    private fun pauseLoading() = animator?.pause()
    private fun resumeLoading() = animator?.resume()

    enum class LoadingState {
        IDLE,
        LOADING,
        PAUSED
    }
}